#include "StreamPuller.h"
#include "VideoReader.h"
#include "Sender.h"
#include "spdlog/spdlog.h"
#include <exception>

TaskReply StreamPuller(const TaskRequest& task)
{
	std::shared_ptr<Sender> sender = nullptr;
	auto cap = VideoReader::Create();
	try {
		SPDLOG_DEBUG("task {}: will open url {}", task.taskId, task.source.url);
		if (!cap->Open(task.source.url)) {
			return TaskReply{task.taskId, -1, "open url error"};
		}
		SPDLOG_DEBUG("task {}: url {} opened", task.taskId, task.source.url);
		sender = Sender::Create(task.target.uri, task.target._root);
	} catch(std::exception& e) {
		return TaskReply{task.taskId, -2, e.what()};
	}
	int pull_fps = (int)(cap->GetFPS() / task.source._fps);
	if (!pull_fps) pull_fps = 1;
	int total = 0, frames = 0;
	
	SPDLOG_DEBUG("task {}: begin to read frame and process", task.taskId);
	FrameCompare fc(task.source._threshold, task.source._scale);
	while (true) {
		try {
			cv::Mat frame;
			if (total % pull_fps == 0) {
				if (!cap->Read(frame)) {
					break;
				}
				if (fc.absdiff(frame)) {
					sender->Send(frame, task.taskId, frames);
					frames++;
				}
			} else {
				if (!cap->Grab()) {
					break;
				}
			}
			total++;
		} catch(std::exception& e) {
			return TaskReply{task.taskId, -3, e.what()};
		}
	}
	SPDLOG_DEBUG("task {}: all frames processed", task.taskId);
	cap->Close();
	sender = nullptr;
	return TaskReply{task.taskId, frames, ""};
}
